#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <cjson/cJSON.h>
#include "auth.h"

char *ak = "API Key";
char *sk = "Secret Key";

int add_history(cJSON *history, char *role, char *content)
{
    cJSON *record = cJSON_CreateObject();
    cJSON_AddStringToObject(record, "role", role);
    cJSON_AddStringToObject(record, "content", content);
    cJSON *messages = cJSON_GetObjectItem(history, "messages");
    if (!messages && !cJSON_IsArray(messages))
    {
        fprintf(stderr, "messages attribute not found\n");
        return 0;
    }
    cJSON_AddItemToArray(messages, record);

    return 1;
}

char *send_request(char *token, char *msg, cJSON *history)
{
    char *respdata;
    size_t respsize;
    FILE *fp = open_memstream(&respdata, &respsize);
    if (!fp)
    {
        perror("open_memstream");
        return NULL;
    }

    CURL *client = curl_easy_init();
    if (!client)
    {
        perror("curl_easy_init");
        fclose(fp);
        return NULL;
    }

    char *url = NULL;
    asprintf(&url, "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/yi_34b_chat?access_token=%s", token);
    curl_easy_setopt(client, CURLOPT_URL, url);

    if (!add_history(history, "user", msg))
    {
        free(url);
        fclose(fp);
        return NULL;
    }

    char *postdata = cJSON_Print(history);
    curl_easy_setopt(client, CURLOPT_POST, 1);
    curl_easy_setopt(client, CURLOPT_POSTFIELDS, postdata);

    // 将服务器返回的响应报文保存到文件流中
    curl_easy_setopt(client, CURLOPT_WRITEDATA, fp);

    CURLcode error = curl_easy_perform(client);
    if (error != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform: %s\n", curl_easy_strerror(error));
        free(url);
        curl_easy_cleanup(client);
        free(postdata);
        fclose(fp);
        return NULL;
    }

    free(url);
    curl_easy_cleanup(client);
    free(postdata);

    fclose(fp);

    return respdata;
}

void process_response(char *response, cJSON *history)
{
    cJSON *root = cJSON_Parse(response);
    if (!root)
    {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL)
        {
            fprintf(stderr, "Error before: %s\n", error_ptr);
        }
        return;
    }

    // 获取转换结果
    cJSON *result = cJSON_GetObjectItem(root, "result");
    if (!result)
    {
        fprintf(stderr, "result attribute not found\n");
        cJSON_Delete(root);
        return;
    }

    puts(result->valuestring);

    add_history(history, "assistant", result->valuestring);

    cJSON_Delete(root);
}

int main()
{
    char *token = get_token(ak, sk);
    if (!token)
    {
        return EXIT_FAILURE;
    }

    cJSON *history = cJSON_CreateObject();
    cJSON_AddArrayToObject(history, "messages");

    char line[80];

    while (fgets(line, sizeof line, stdin))
    {
        char *response = send_request(token, line, history);
        if (!response) continue;
        process_response(response, history);
    }

    return 0;
}
